package cate.game.chat;

import cate.common.rpc.path.RpcCommonPath;
import cate.common.table.d.GDChat;
import cate.game.chat.msg.ChatPrivateItemResp;
import cate.game.chat.msg.ChatPublicItemResp;
import cate.game.framework.ModuleMan;
import cate.game.role.Role;
import cate.game.role.friend.Friend;
import cp.solution.rpc.RpcMsgHead;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 聊天模块
 */
public class ChatManager extends ModuleMan {

    /**
     * 聊天历史
     */
    public ChatHistory history = new ChatHistory();
    private final Map<String, Map<String, OfflinePrivateChatItem>> chatCache = new ConcurrentHashMap<>();

    @Override
    public void initDependent() throws Exception {
        game.rpcRecv().onFireAndForgetTemplate(RpcCommonPath.CHAT_G2G, ChatPublicItem.class, this::onChatMessageHandler);
    }

    private void onChatMessageHandler(RpcMsgHead head, ChatPublicItem message) {
        switch (message.channel) {
            case GDChat.Channel.CROSS:
            case GDChat.Channel.CHAMPION_RACE:
                game.chat.handleCross(message);
                break;
            case GDChat.Channel.ZONE:
                game.chat.handleZone(message);
                break;
            case GDChat.Channel.GROUP:
            case GDChat.Channel.THRONE_BATTLE:
                game.chat.handleGroup(message);
                break;
            case GDChat.Channel.ELITE_RACE:
                game.chat.handleEliteRace(message);
                break;
            default:
                break;
        }
    }

    /**
     * 发送到公共频道
     */
    public void sendPublic(ChatPublicItem item, ChatFilter filter) {
        this.history.addPublic(game, item, filter);
        ChatPublicItemResp resp = new ChatPublicItemResp(item);
        if (filter == null || filter.none()) {
            // 发送给全体在线玩家
            game.role.activeForOnlineSelfThread(m -> m.sendNow(resp));
        } else {
            // 要进行筛选
            game.role.activeForOnlineSelfThread(
                    role -> {
                        if (filter.accept(item, role)) {
                            role.sendNow(resp);
                        }
                    });
        }
    }

    public void sendSelfPublic(Role role, ChatPublicItem item) {
        if (role == null) {
            return;
        }
        ChatPublicItemResp resp = new ChatPublicItemResp(item);
        role.sendNow(resp);
    }

    /**
     * 发送到私人聊天
     */
    public void sendPrivate(Role sender, String toId, int contentId, String content, List<ChatContentParam> params) {
        Friend friend = sender.getFriend().getFriend(toId);
        if (friend == null) {
            game.notice.message(sender,  "对方不是您的好友，无法进行私聊");
            return;
        }
        content = game.tools.sensitiveWords.replace(content);
        ChatPublicItem item = new ChatPublicItem(sender, GDChat.Channel.PRIVATE, contentId, content, params);
        ChatPrivateItem bigItem = new ChatPrivateItem(toId, item);
        Role to = game.role.getRole(toId);
        if (to == null) {
            return;
        }
        if (to.getFriend().inBlackList(sender.getUid())) {
            game.notice.message(sender, "对方已经将您拉黑，无法对其发起私聊");
            return;
        }
        sender.sendNow(new ChatPrivateItemResp(item, toId));
        sendPrivate(bigItem, to);
    }

    public void handleCross(ChatPublicItem item) {
        if (item == null) {
            return;
        }
        ChatFilter filter = item.filter;
        if (filter == null) {
            filter = new ChatFilter();
        }
        game.chat.sendPublic(item, filter);
    }

    public void handleGroup(ChatPublicItem item) {
        if (item == null) {
            return;
        }
        game.chat.sendPublic(item, null);
    }

    public void handleZone(ChatPublicItem item) {
        if (Objects.isNull(item)) {
            return;
        }

        game.chat.sendPublic(item, null);
    }

    public void handleEliteRace(ChatPublicItem item) {
        if (Objects.isNull(item)) {
            return;
        }

        game.chat.sendPublic(item, null);
    }

    public void sendCross(ChatPublicItem item) {
        game.rpcSend().fireAndForgetGameInCross(RpcCommonPath.CHAT_G2G, item);
    }

    public void sendGroup(ChatPublicItem item) {
        game.rpcSend().fireAndForgetGameInGroup(RpcCommonPath.CHAT_G2G, item);
    }

    /**
     * 添加私聊内容
     */
    private void sendPrivate(ChatPrivateItem privateItem, Role role) {
        ChatPublicItem item = privateItem.item;
        if (role.getStatus().isOnline()) {
            role.sendNow(new ChatPrivateItemResp(item, role.getUid()));
            return;
        }
        addToCache(privateItem);
    }

    private void addToCache(ChatPrivateItem privateItem) {
        ChatPublicItem item = privateItem.item;
        Map<String, OfflinePrivateChatItem> map = chatCache.computeIfAbsent(privateItem.toId, e -> new HashMap<>());
        OfflinePrivateChatItem chatItem = map.computeIfAbsent(item.sender.id, e -> new OfflinePrivateChatItem(item.sender));
        chatItem.addChat(item);
    }

    public Map<String, OfflinePrivateChatItem> getRoleOfflineHistory(Role role) {
        Map<String, OfflinePrivateChatItem> his = chatCache.get(role.getUid());
        chatCache.remove(role.getUid());
        return his == null ? new HashMap<>() : his;
    }
}
